﻿using Gw2Api;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Newtonsoft.Json;

namespace Gw2Overlay
{
    public class WindowInfo
    {
        public int map;
        public string matchup;
        public string server;
        public double top;
        public double left;
        public double width;
        public double height;
        public double opacity;
        public string sound;
        public string naming;
        public string spokenNames;
        public string speakMapNames;
        public string voice;
        public bool autoMap;
    }

    /// <summary>
    /// Interaction logic for OverlordWindow.xaml
    /// </summary>
    public partial class OverlordWindow : OverlayWindow
    {
        private Dictionary<Window, WindowInfo> _windows;
        private WvWApi api;

        public OverlordWindow() : base(true)
        {
            _windows = new Dictionary<Window, WindowInfo>();
            api = Gw2ApiFactory.WvWApi;
            api.Ready += new BaseApi.ReadyHandler(ApiReady);
            InitializeComponent();
        }

        protected override void OnInteractable(bool interactable)
        {
            if (interactable)
            {
                backrect.Visibility = System.Windows.Visibility.Visible;
            }
            else
            {
                backrect.Visibility = System.Windows.Visibility.Hidden;
            }
        }

        override public void DoHitTest(Point pt)
        {
            foreach (GraphWindow win in _windows.Keys)
            {
                win.DoHitTest(pt);
            }
        }

        public void SetShowStatusTooltip(bool show)
        {
            foreach (GraphWindow win in _windows.Keys)
            {
                win.wvWMapControl1.ShowStatusTooltip = show;
            }
        }

        override protected void MakeClickThroughAfter(bool transparent)
        {
            foreach (GraphWindow win in _windows.Keys)
            {
                win.MakeClickThrough(transparent);
            }
        }

        private void ApiReady()
        {
            LoadWindows();
            this.Visibility = System.Windows.Visibility.Hidden;
        }

        private void LoadWindows()
        {
            List<WindowInfo> windows;
            try
            {
                string info = Properties.Settings.Default.WindowPosition;
                windows = JsonConvert.DeserializeObject<List<WindowInfo>>(info);
                if (windows.Count == 0)
                    throw new Exception();
            }
            catch (Exception)
            {
                windows = new List<WindowInfo>();
                WindowInfo wi = new WindowInfo();
                wi.map = (int)WvWMaps.Center;
                wi.matchup = "1-1";
                wi.top = 0;
                wi.left = 0;
                wi.autoMap = false;
                windows.Add(wi);
            }
            Properties.Settings.Default.WindowPosition = JsonConvert.SerializeObject(windows);
            App.SaveSettings();
            CreateWindows(windows);
        }

        private void CreateWindows(List<WindowInfo> windows)
        {
            foreach (var wi in windows)
            {
                CreateNewGraphWindow((WvWMaps)wi.map, wi.matchup, wi.top, wi.left, wi.width, wi.height, wi.opacity, wi.sound, wi.autoMap, wi.naming, wi.spokenNames, wi.speakMapNames, wi.voice, wi.server);
            }
        }

        public void CreateNewGraphWindow(WvWMaps map, string matchup, double top, double left, double width = 0, double height = 0, double opacity = 1, string sound = "", bool autoMap = false, string naming = "", string spokenNames = "", string speakMapNames = "", string voice = null, string server = null)
        {
            GraphWindow gw = new GraphWindow(this);
            WindowInfo wi = new WindowInfo();

            if (width == 0)
            {
                width = (int)GraphWindowSizes.Medium;
            }
            if (height == 0)
            {
                height = (int)GraphWindowSizes.Medium;
            }
            if (opacity < 0.2)
            {
                opacity = 1;
            }

            wi.map = (int)map;
            wi.matchup = matchup;
            wi.top = top;
            wi.left = left;
            wi.width = width;
            wi.height = height;
            wi.opacity = opacity;
            wi.autoMap = autoMap;
            wi.voice = voice;
            wi.server = server;
            gw.wvWMapControl1.WvWMap = map;
            if (autoMap)
            {
                gw.wvWMapControl1.PositionApi = Gw2ApiFactory.PositionApi;
            }
            if (server != null)
            {
                gw.wvWMapControl1.WvWMatchup = api.GetMatchupByWorldNameV2(Gw2ApiFactory.WorldNameApi.GetWorldFromId(server)).id;
            }
            else
            {
                gw.wvWMapControl1.WvWMatchup = matchup;
            }
            gw.Top = top;
            gw.Left = left;
            gw.Width = width;
            gw.Height = height;
            gw.Opacity = opacity;
            AudioNotification au = AudioNotification.None;
            if (Enum.TryParse<AudioNotification>(sound, true, out au))
            {
                gw.audio = au;
                wi.sound = au.ToString();
            }
            else
            {
                gw.audio = AudioNotification.None;
                wi.sound = AudioNotification.None.ToString();
            }
            NamingConvention nc = NamingConvention.Names;
            if (Enum.TryParse<NamingConvention>(naming, true, out nc))
            {
                gw.naming = nc;
                wi.naming = nc.ToString();
            }
            else
            {
                gw.naming = NamingConvention.Names;
                wi.naming = NamingConvention.Names.ToString();
            }
            SpokenWorldNames sn = SpokenWorldNames.Names;
            if (Enum.TryParse<SpokenWorldNames>(spokenNames, true, out sn))
            {
                gw.spokenNames = sn;
                wi.spokenNames = sn.ToString();
            }
            else
            {
                gw.spokenNames = SpokenWorldNames.Names;
                wi.spokenNames = SpokenWorldNames.Names.ToString();
            }
            SpeakMapNames smn = SpeakMapNames.Auto;
            if (Enum.TryParse<SpeakMapNames>(speakMapNames, true, out smn))
            {
                gw.speakMapNames = smn;
                wi.speakMapNames = smn.ToString();
            }
            else
            {
                gw.speakMapNames = SpeakMapNames.Auto;
                wi.speakMapNames = SpeakMapNames.Auto.ToString();
            }
            gw.voice = voice;
            if (voice != null)
            {
                TtsService.Instance.SelectVoice(voice);
            }
            gw.server = server;
            _windows.Add(gw, wi);
            gw.Show();
        }

        public void UpdateInfo(GraphWindow window)
        {
            WindowInfo wi = new WindowInfo();
            wi.map = (int)window.wvWMapControl1.WvWMap;
            wi.matchup = window.wvWMapControl1.WvWMatchup;
            wi.top = window.Top;
            wi.left = window.Left;
            wi.width = window.Width;
            wi.height = window.Height;
            wi.opacity = window.Opacity;
            wi.sound = window.audio.ToString();
            wi.naming = window.naming.ToString();
            wi.spokenNames = window.spokenNames.ToString();
            wi.speakMapNames = window.speakMapNames.ToString();
            wi.autoMap = (window.wvWMapControl1.PositionApi != null);
            wi.voice = window.voice;
            wi.server = window.server;

            _windows[window] = wi;

            Properties.Settings.Default.WindowPosition = JsonConvert.SerializeObject(_windows.Select(kv => kv.Value).ToList());
            App.SaveSettings();
        }

        public void CloseWindow(GraphWindow window)
        {
            if (_windows.Count > 1)
            {
                _windows.Remove(window);
            }
            else
            {
                Shutdown();
            }

            Properties.Settings.Default.WindowPosition = JsonConvert.SerializeObject(_windows.Select(kv => kv.Value).ToList());
            App.SaveSettings();
        }

        public int WindowCount
        {
            get
            {
                return _windows.Count;
            }
        }

        public void Shutdown()
        {
            Properties.Settings.Default.WindowPosition = JsonConvert.SerializeObject(_windows.Select(kv => kv.Value).ToList());
            App.SaveSettings();
            Application.Current.Shutdown();
        }

        private void ShutdownClick(object sender, RoutedEventArgs e)
        {
            this.Shutdown();
        }
    }
}
